package org.thanos.demo.core;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorBigInt;
import com.googlecode.aviator.runtime.type.AviatorObject;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class StartupListener implements ApplicationListener<ApplicationReadyEvent> {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        execute();
        compile();
        customFunction();
    }

    /**
     * 执行方法
     */
    private void execute(){
        String str = "小哥哥带你使用金鱼";
        Map<String,Object> env = new HashMap<>();
        env.put("str",str);
        // string.length()  :  内置方法
        Long length = (Long)AviatorEvaluator.execute("string.length(str)",env);
        System.out.println(length);
    }

    /**
     * 计算
     */
    private void compile(){
        String expression = "a-(b-c)>100";
        Expression compiledExp = AviatorEvaluator.compile(expression);
        Map<String, Object> env = new HashMap<>();
        env.put("a", 100.3);
        env.put("b", 45);
        env.put("c", -199.100);
        Boolean result = (Boolean) compiledExp.execute(env);
        System.out.println(result);
    }

    /**
     * 自定义函数
     */
    public void customFunction() {
        AviatorEvaluator.addFunction(new MinFunction());
        // 编写表达式
        String expression = "customMin(a,b)";
        // 表达式编译
        Expression compiledExp = AviatorEvaluator.compile(expression, true);
        Map<String, Object> env = new HashMap<>();
        env.put("a", 100.3);
        env.put("b", 45);
        // 执行表达式, 返回结果转为Double格式
        Double result = (Double) compiledExp.execute(env);
        System.out.println(result);
    }
    // 自定义函数类必须继承AbstractFunction类, 重写call() 和 getName()
    static class MinFunction extends AbstractFunction {
        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            // 编写方法处理逻辑, 对比两个输入数字返回最小的
            Number left = FunctionUtils.getNumberValue(arg1, env);
            Number right = FunctionUtils.getNumberValue(arg2, env);
            return new AviatorBigInt(Math.min(left.doubleValue(), right.doubleValue()));
        }
        @Override
        public String getName() {
            // 设置方法名
            return "customMin";
        }
    }
}
